﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Xajhzwb.Components.Data;
using Xajhzwb.Components.Util;
using Xajhzwb.Components.Helper;
using System.Text.RegularExpressions;

namespace Xajhzwb.Components.Gather
{
    public class GetWeb
    {
        DataTable tempData;
        private static readonly int DEF_PACKET_LENGTH = 2048;

        protected string WebPageSource { get; set; }
        public List<WebPageCutFlag> CutFlag { get; set; }

        public GetWeb()
        {
            this.CutFlag = new List<WebPageCutFlag>();
        }

        public DataTable GetWebData(string url, GatherData getData)
        {
            tempData = new DataTable("tempData");
            int i;
            int j;
            string strCut = "";

            for(i = 0; i < this.CutFlag.Count; i++)
            {
                tempData.Columns.Add(new DataColumn(this.CutFlag[i].Title, typeof(string)));
            }

            for(i = 0; i < this.CutFlag.Count; i++)
            {
                strCut += "(?<" + this.CutFlag[i].Title + ">" + WebHelper.RegexReplaceTrans(this.CutFlag[i].StartPos) + ")";

                switch(this.CutFlag[i].LimitSign)
                {
                    case (int)Const.LimitSign.NoLimit:
                        strCut += ".*?";
                        break;
                    case (int)Const.LimitSign.NoWebSign:
                        strCut += "[^<>]*?";
                        break;
                    case (int)Const.LimitSign.OnlyCN:
                        strCut += "[\\u4e00-\\u9fa5]*?";
                        break;
                    case (int)Const.LimitSign.OnlyDoubleByte:
                        strCut += "[^\\x00-\\xff]*?";
                        break;
                    case (int)Const.LimitSign.OnlyNumber:
                        strCut += "[\\d]*?";
                        break;
                    case (int)Const.LimitSign.OnlyChar:
                        strCut += "[\\x00-\\xff]*?";
                        break;
                    case (int)Const.LimitSign.Custom:
                        strCut += this.CutFlag[i].RegionExpression.ToString();
                        break;
                    default:
                        strCut += "[\\S\\s]*?";
                        break;
                }
                strCut += "(?=" + WebHelper.RegexReplaceTrans(this.CutFlag[i].EndPos) + ")|";
            }

            int rowCount = this.CutFlag.Count;
            strCut = strCut.Substring(0, strCut.Length - 1);

            if(Regex.IsMatch(url, "[\"\\s]"))
            {
                Match aa = Regex.Match(url, "[\"\\s]");
                tempData = null;
                return tempData;
            }

            try
            {
                Config config = new Config();
                WebPageSource = WebHelper.GetHtmlSource(url, Encoding.Default, getData.lgcookies, config.UserAgent, 
                                                        config.ReadTimeout, config.ProxyServer, config.ProxyPort, config.ProxyUser, config.ProxyPass);
            }
            catch(System.Web.HttpException ex)
            {
                throw ex;
            }

            Regex re = new Regex(@strCut, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            MatchCollection mc = re.Matches(this.WebPageSource);

            if(mc.Count == 0)
            {
                tempData = null;
                return tempData;
            }

            DataRow drNew = null;
            i = 0;

            int rows = 0;
            int m = 0;

            try
            {

                while(m < mc.Count)
                {
                    drNew = tempData.NewRow();
                    rows++;

                    for(i = 0; i < this.CutFlag.Count; i++)
                    {

                        if(m < mc.Count)
                        {
                            if(i == 0)
                            {
                                while(!mc[m].Value.StartsWith(this.CutFlag[i].StartPos, StringComparison.CurrentCultureIgnoreCase))
                                {
                                    m++;
                                    if(m >= mc.Count)
                                    {
                                        goto ExitWhile;
                                    }
                                }

                                drNew[i] = mc[m].Value.Substring(this.CutFlag[i].StartPos.Length, mc[m].Value.Length - this.CutFlag[i].StartPos.Length);

                                m++;
                            }
                            else
                            {
                                if(mc[m].Value.StartsWith(this.CutFlag[i].StartPos, StringComparison.CurrentCultureIgnoreCase))
                                {

                                    drNew[i] = mc[m].Value.Substring(this.CutFlag[i].StartPos.Length, mc[m].Value.Length - this.CutFlag[i].StartPos.Length);

                                    m++;
                                }
                                else
                                {
                                    if(mc[m].Value.StartsWith(this.CutFlag[i - 1].StartPos, StringComparison.CurrentCultureIgnoreCase))
                                    {
                                        m++;
                                        i--;
                                    }
                                    else
                                    {
                                        if(i < this.CutFlag.Count - 1)
                                        {
                                            if(mc[m].Value.StartsWith(this.CutFlag[i + 1].StartPos, StringComparison.CurrentCultureIgnoreCase))
                                            {

                                            }
                                            else
                                            {
                                                m++;
                                                i--;
                                            }
                                        }
                                        else
                                        {
                                            m++;
                                            i--;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    tempData.Rows.Add(drNew);
                    drNew = null;

                }
            }
            catch(System.Exception ex)
            {
                throw ex;
            }

            ExitWhile:

            for(i = 0; i < this.CutFlag.Count; i++)
            {
                if(this.CutFlag[i].ExportExpression != "")
                {
                    for(int index = 0; index < tempData.Rows.Count; index++)
                    {
                        string oStr = this.CutFlag[i].ExportExpression.Substring(1, this.CutFlag[i].ExportExpression.IndexOf(",") - 2);
                        string nStr = this.CutFlag[i].ExportExpression.Substring(this.CutFlag[i].ExportExpression.IndexOf(",") + 2, this.CutFlag[i].ExportExpression.Length - this.CutFlag[i].ExportExpression.IndexOf(",") - 3);
                        tempData.Rows[index][i] = Regex.Replace(tempData.Rows[index][i].ToString(), oStr, nStr, RegexOptions.IgnoreCase | RegexOptions.Multiline);
                    }
                }
            }

            for(i = 0; i < rows; i++)
            {
                for(j = 0; j < this.CutFlag.Count; j++)
                {
                    if(this.CutFlag[j].IsDownFile)
                    {
                        string fileUrl = tempData.Rows[i][j].ToString();
                        string downloadFileName = "";

                        Regex s = new Regex(@"(?<=/)[^/]*", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                        MatchCollection urlstr = s.Matches(fileUrl);
                        if(urlstr.Count == 0)
                            downloadFileName = fileUrl;
                        else
                            downloadFileName = urlstr[urlstr.Count - 1].ToString();
                        //downloadFileName = sPath + "\\" + downloadFileName;

                        if(string.Compare(fileUrl.Substring(0, 4), "http", true) == 0)
                        {
                            WebHelper.DownloadFile(fileUrl, "", getData.lgcookies);
                        }
                        else
                        {
                            //if(fileUrl.Substring(0, 1) == "/")
                            //{
                            //    Url = Url.Substring(7, Url.Length - 7);
                            //    Url = fileUrl.Substring(0, Url.IndexOf("/"));
                            //    Url = "http://" + Url;
                            //    FileUrl = Url + fileUrl;
                            //}
                            //else if(FileUrl.IndexOf("/") <= 0)
                            //{
                            //    Url = Url.Substring(0, Url.LastIndexOf("/") + 1);
                            //    FileUrl = Url + FileUrl;
                            //}
                            //else
                            //{
                            //    Url = Url.Substring(0, Url.LastIndexOf("/") + 1);
                            //    FileUrl = Url + FileUrl;
                            //}

                            WebHelper.DownloadFile(fileUrl, "", getData.lgcookies);
                        }
                    }
                }
            }

            return tempData;
        }
    }
}
